#include "attendencewin.h"
#include "./ui_attendencewin.h"
#include <QPixmap>
#include <QDebug>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSqlError>
#include <QDateTime>
#include <QMessageBox>
#include <QFile>
#include <QThread>

attendenceWin::attendenceWin(QWidget *parent)
    : QMainWindow(parent), ui(new Ui::attendenceWin)
{
    ui->setupUi(this);
    serverSocket = new QTcpServer(this);
    serverSocket->listen(QHostAddress::Any, 8080);
    connect(serverSocket, &QTcpServer::newConnection, this, &attendenceWin::newConnection);

    // 初始化人脸识别对象
    faceObject = new QFaceObject(this);

    // 数据库连接已在main.cpp中初始化，这里不需要重复创建
    QSqlDatabase db = QSqlDatabase::database(); // 使用默认连接
    if (!db.isOpen())
    {
        qDebug() << "数据库连接失败:" << db.lastError().text();
    }
    else
    {
        qDebug() << "使用现有数据库连接成功";
    }

    bsize = 0;
    attendanceRecorded = false; // 初始化考勤记录状态

    // 直接连接信号槽，不使用单独线程避免数据库跨线程问题
    connect(this, &attendenceWin::query, faceObject, [=](cv::Mat image)
            {
                faceObject->face_query(image, 0.7f); // 使用默认相似度阈值0.7
            });
    // 关联QFaceObject对象里面的sendEmployeeDataToClient信号
    connect(faceObject, &QFaceObject::sendEmployeeDataToClient, this, &attendenceWin::sendEmployeeDataToClient);
}

attendenceWin::~attendenceWin()
{
    delete ui;
    if (faceObject)
    {
        delete faceObject;
    }
}

void attendenceWin::newConnection()
{
    tcpSocket = serverSocket->nextPendingConnection();
    connect(tcpSocket, &QTcpSocket::readyRead, this, &attendenceWin::read_data);
    attendanceRecorded = false; // 新连接时重置考勤记录状态
    qDebug() << "新客户端连接，重置考勤状态";
}

void attendenceWin::read_data()
{
    QDataStream stream(tcpSocket); // 把套接字绑定到数据流
    stream.setVersion(QDataStream::Qt_6_8);

    if (bsize == 0)
    {
        if (tcpSocket->bytesAvailable() < (qint64)sizeof(bsize))
            return;
        // 采集数据的长度
        stream >> bsize;
    }

    if (tcpSocket->bytesAvailable() < bsize) // 说明数据还没有发送完成，返回继续等待
    {
        return;
    }
    QByteArray data;
    stream >> data;
    bsize = 0;
    if (data.size() == 0) // 没有读取到数据
    {
        return;
    }

    if (!data.isEmpty())
    {
        // 将接收到的图像数据转换为QPixmap并显示在picLb标签上
        QPixmap pixmap;
        if (pixmap.loadFromData(data, "jpg"))
        {
            pixmap = pixmap.scaled(ui->picLb->size());
            ui->picLb->setPixmap(pixmap);
            qDebug() << "Image received and displayed, size:" << data.size() << "bytes";

            // 将QByteArray转换为cv::Mat进行人脸识别
            std::vector<uchar> decode;
            decode.resize(data.size());
            memcpy(decode.data(), data.data(), data.size());
            cv::Mat faceImage = cv::imdecode(decode, cv::IMREAD_COLOR);

            if (!faceImage.empty())
            {
                // 发送人脸识别信号，提高数据接收效率
                emit query(faceImage);
            }
        }
    }
}

void attendenceWin::sendEmployeeDataToClient(int faceId)
{
    qDebug() << "接收到faceID:" << faceId;

    // 判断faceId是否大于等于0
    if (faceId < 0)
    {
        qDebug() << "无效的faceID:" << faceId;
        return;
    }

    // 根据faceId查询employeeID
    QSqlQuery faceQuery;
    faceQuery.prepare("SELECT employeeID FROM employee WHERE faceID = ?");
    faceQuery.addBindValue(faceId);

    if (!faceQuery.exec() || !faceQuery.next())
    {
        qDebug() << "未找到对应的员工，faceID:" << faceId;
        return;
    }

    int employeeID = faceQuery.value(0).toInt();
    qDebug() << "查询到员工ID:" << employeeID;
    qDebug() << "处理员工ID:" << employeeID;

    // 检查当前会话是否已经记录过考勤
    if (attendanceRecorded)
    {
        qDebug() << "当前会话已记录考勤，跳过重复处理";
        if (tcpSocket && tcpSocket->state() == QTcpSocket::ConnectedState)
        {
            tcpSocket->disconnectFromHost();
        }
        return;
    }

    // 使用解耦的函数查询考勤记录
    bool hasAttendanceToday = checkAttendanceRecord(employeeID);
    int attendanceStatus = 0; // 0: 考勤成功, 1: 已完成考勤

    // 根据是否有考勤记录决定操作
    if (hasAttendanceToday)
    {
        // 已有考勤记录，设置标志位为已完成考勤
        attendanceStatus = 1;
        qDebug() << "员工ID" << employeeID << "今天已有考勤记录";
    }
    else
    {
        // 使用解耦的函数写入新记录
        if (insertAttendanceRecord(employeeID))
        {
            attendanceStatus = 0; // 考勤成功
        }
        else
        {
            qDebug() << "考勤记录插入失败，无法继续处理";
            return;
        }
    }

    // 查询员工详细信息
    QSqlQuery employeeQuery;
    employeeQuery.prepare("SELECT name, headfile FROM employee WHERE employeeID = ?");
    employeeQuery.addBindValue(employeeID);

    if (!employeeQuery.exec() || !employeeQuery.next())
    {
        qDebug() << "未找到员工详细信息，employeeID:" << employeeID;
        return;
    }

    QString name = employeeQuery.value(0).toString();
    QString headfile = employeeQuery.value(1).toString();
    QString currentTime = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");

    qDebug() << "查询到员工信息 - ID:" << employeeID << "姓名:" << name << "头像:" << headfile;

    // 发送数据给客户端
    if (!tcpSocket || tcpSocket->state() != QTcpSocket::ConnectedState)
    {
        qDebug() << "TCP连接无效，无法发送数据";
        return;
    }

    // 读取头像文件
    QByteArray imageData;
    QString imagePath = headfile;
    QFile imageFile(imagePath);

    if (imageFile.open(QIODevice::ReadOnly))
    {
        imageData = imageFile.readAll();
        imageFile.close();
        qDebug() << "成功读取头像文件:" << imagePath << "大小:" << imageData.size() << "字节";
    }
    else
    {
        qDebug() << "无法读取头像文件:" << imagePath;
    }

    // 准备发送的数据
    QByteArray sendData;
    QDataStream stream(&sendData, QIODevice::WriteOnly);
    stream.setVersion(QDataStream::Qt_6_8);

    // 按照协议发送数据：工号、姓名、时间、考勤状态标志位、图像数据大小、图像数据
    stream << employeeID;
    stream << name;
    stream << currentTime;
    stream << attendanceStatus; // 添加考勤状态标志位
    stream << (quint32)imageData.size();
    stream.writeRawData(imageData.data(), imageData.size());

    // 发送数据大小
    QByteArray sizeData;
    QDataStream sizeStream(&sizeData, QIODevice::WriteOnly);
    sizeStream.setVersion(QDataStream::Qt_6_8);
    sizeStream << (quint64)sendData.size();

    // 先发送数据大小，再发送实际数据
    tcpSocket->write(sizeData);
    tcpSocket->write(sendData);
    tcpSocket->flush();

    QString statusText = (attendanceStatus == 0) ? "考勤成功" : "已完成考勤";
    qDebug() << "已发送员工数据给客户端 - 工号:" << employeeID << "姓名:" << name << "时间:" << currentTime << "状态:" << statusText << "数据大小:" << sendData.size() << "字节";

    // 标记已处理考勤
    attendanceRecorded = true;

    // 发送完成后断开连接
    tcpSocket->disconnectFromHost();
    qDebug() << "数据发送完成，断开客户端连接";
}

// 查询当天考勤记录
bool attendenceWin::checkAttendanceRecord(int employeeID)
{
    QSqlQuery query;
    query.prepare("SELECT COUNT(*) FROM attendance WHERE employeeID = ? AND DATE(attendace) = DATE('now')");
    query.addBindValue(employeeID);

    if (query.exec() && query.next())
    {
        int todayCount = query.value(0).toInt();
        return (todayCount > 0);
    }

    qDebug() << "查询考勤记录失败:" << query.lastError().text();
    return false;
}

// 插入新的考勤记录
bool attendenceWin::insertAttendanceRecord(int employeeID)
{
    QString currentTime = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");
    QSqlQuery query;
    query.prepare("INSERT INTO attendance (employeeID, attendace) VALUES (?, ?)");
    query.addBindValue(employeeID);
    query.addBindValue(currentTime);

    if (query.exec())
    {
        qDebug() << "考勤记录插入成功 - 员工ID:" << employeeID << "时间:" << currentTime;
        return true;
    }
    else
    {
        qDebug() << "考勤记录插入失败:" << query.lastError().text();
        return false;
    }
}